﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using AvatarDAL;
using System.Data.Linq;
using AvatarMembershipDAL;
using AvatarMembership.Model;

namespace AvatarHelper
{
    public static class DBHelper
    {
        public const string ConnectionStringName = "AvatarConnectionString";
        public const string MembershipConnectionStringName = "SqlServices";

        public static AvatarDataContext GetDataContext()
        {
            try
            {
                var _adc = new AvatarDataContext(ConfigurationManager.ConnectionStrings[ConnectionStringName].ConnectionString);

                return _adc;
            }
            catch (Exception _e)
            {
                //throw new Exception("ConnectionStrings is null or Wrong!");
                throw new Exception(_e.Message);
            }
        }
        public static AvatarMembershipDataContext GetMembershipDataContext()
        {
            try
            {
                var _adc = new AvatarMembershipDataContext(ConfigurationManager.ConnectionStrings[MembershipConnectionStringName].ConnectionString);

                return _adc;
            }
            catch (Exception _e)
            {
                //throw new Exception("ConnectionStrings is null or Wrong!");
                throw new Exception(_e.Message);
            }
        }
        
        /// <summary>
        /// 获取对象列表
        /// </summary>
        /// <typeparam name="T">获取对象类型</typeparam>
        /// <param name="_errorHead">错误信息标头</param>
        /// <returns>对象列表</returns>
        public static List<T> GetAll<T>(string _errorHead) where T : class
        {
            List<T> _list = new List<T>();
            try
            {
                using (var _sdc = GetDataContext())
                {
                    _list = _sdc.GetTable<T>().ToList();
                }
            }
            catch (Exception _e)
            {
                throw new Exception(_errorHead + _e.Message);
            }
            return _list;
        }
        
        /// <summary>
        /// 获取对象列表
        /// </summary>
        /// <typeparam name="T">获取对象类型</typeparam>
        /// <param name="_where">查询条件</param>
        /// <param name="_errorHead">错误信息标头</param>
        /// <returns>对象列表</returns>
        public static List<T> GetAll<T>(Func<T,bool> _where,string _errorHead) where T : class
        {
            List<T> _list = new List<T>();
            try
            {
                using (var _sdc = GetDataContext())
                {
                    _list = _sdc.GetTable<T>().Where(_where).ToList();
                }
            }
            catch (Exception _e)
            {
                throw new Exception(_errorHead + _e.Message);
            }
            return _list;
        }

        public static List<T> GetAll<T>(Func<T, bool> _where,int _take, string _errorHead) where T : class
        {
            List<T> _list = new List<T>();
            try
            {
                using (var _sdc = GetDataContext())
                {
                    _list = _sdc.GetTable<T>().Where(_where).Take(_take).ToList();
                }
            }
            catch (Exception _e)
            {
                throw new Exception(_errorHead + _e.Message);
            }
            return _list;
        }

        /// <summary>
        /// 获取对象列表（排序）
        /// </summary>
        /// <typeparam name="T">获取对象类型</typeparam>
        /// <param name="_orderby">排序条件</param>
        /// <param name="_errorHead">错误信息标头</param>
        /// <returns>对象列表</returns>
        public static List<T> GetAll<T>(Func<T, int> _orderby, string _errorHead) where T : class
        {
            List<T> _list = new List<T>();
            try
            {
                using (var _sdc = GetDataContext())
                {
                    _list = _sdc.GetTable<T>().OrderBy(_orderby).ToList();
                }
            }
            catch (Exception _e)
            {
                throw new Exception(_errorHead + _e.Message);
            }
            return _list;
        }

        public static List<T> GetAll<T>(Func<T, int> _orderby, int _take, string _errorHead) where T : class
        {
            List<T> _list = new List<T>();
            try
            {
                using (var _sdc = GetDataContext())
                {
                    _list = _sdc.GetTable<T>().Take(_take).OrderBy(_orderby).ToList();
                }
            }
            catch (Exception _e)
            {
                throw new Exception(_errorHead + _e.Message);
            }
            return _list;
        }

        /// <summary>
        /// 获取对象列表（排序、查询条件）
        /// </summary>
        /// <typeparam name="T">获取对象类型</typeparam>
        /// <param name="_where">查询条件</param>
        /// <param name="_orderby">排序条件</param>
        /// <param name="_errorHead">错误信息标头</param>
        /// <returns></returns>
        public static List<T> GetAll<T>(Func<T, bool> _where, Func<T, int> _orderby, string _errorHead) where T : class
        {
            List<T> _list = new List<T>();
            try
            {
                using (var _sdc = GetDataContext())
                {
                    _list = _sdc.GetTable<T>().Where(_where).OrderBy(_orderby).ToList();
                }
            }
            catch (Exception _e)
            {
                throw new Exception(_errorHead + _e.Message);
            }
            return _list;
        }

        /// <summary>
        /// 获取单独对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="_where">查询条件</param>
        /// <returns>对象</returns>
        public static T Get<T>(Func<T, bool> _where, string _errorHead) where T : class
        {
            try
            {
                using (var _sdc = DBHelper.GetDataContext())
                {
                    return _sdc.GetTable<T>().FirstOrDefault(_where);
                }
            }
            catch (Exception _e)
            {
                throw new Exception(_errorHead + _e.Message);
            }
        }

        /// <summary>
        /// 更新对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="_object"></param>
        /// <param name="_update"></param>
        public static bool Update<T>(T _object, Action<T> _update, string _errorHead) where T : class
        {
            bool _ok = false;
            try
            {
                using (var _sdc = GetDataContext())
                {
                    _sdc.GetTable<T>().Attach(_object);
                    _update(_object);

                    _sdc.SubmitChanges();
                }
                _ok = true;
            }
            catch (Exception _e)
            {
                throw new Exception(_errorHead + _e.Message);
            }

            return _ok;
        }

        /// <summary>
        /// 批量更新对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="items"></param>
        /// <param name="update"></param>
        public static bool UpdateAll<T>(List<T> items, Action<T> update, string _errorHead) where T : class
        {
            bool _ok = false;
            try
            {
                using (var _db = GetDataContext())
                {
                    Table<T> table = _db.GetTable<T>();
                    foreach (T item in items)
                    {
                        table.Attach(item);
                        update(item);
                    }
                    _db.SubmitChanges();
                }
                _ok = true;
            }
            catch (Exception _e)
            {
                throw new Exception(_errorHead+_e.Message);
            }
            return _ok;
        }
        
        /// <summary>
        /// 删除对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="_entity"></param>
        public static bool Delete<T>(T _entity, string _errorHead) where T : class, new()
        {
            bool _ok = false;
            try
            {
                using (var _db = GetDataContext())
                {
                    Table<T> table = _db.GetTable<T>();
                    table.Attach(_entity);
                    table.DeleteOnSubmit(_entity);

                    _db.SubmitChanges();
                }
                _ok = true;
            }
            catch (Exception _e)
            {
                throw new Exception(_errorHead+_e.Message);
            }
            return _ok;
        }
        
        /// <summary>
        /// 添加对象
        /// </summary>
        /// <typeparam name="T">添加的对象类型</typeparam>
        /// <param name="_object">要添加的对象</param>
        /// <param name="_duplication">防止重复添加的筛选条件</param>
        /// <param name="_errorHead">错误信息的标头</param>
        /// <returns></returns>
        public static bool Insert<T>(T _object, Func<T, bool> _duplication, string _errorHead) where T : class
        {
            bool _ok = false;
            try
            {
                using (var _sdc = GetDataContext())
                {
                    var _b = _sdc.GetTable<T>().Where(_duplication).FirstOrDefault();
                    if (_b == null)
                    {
                        _sdc.GetTable<T>().InsertOnSubmit(_object);

                        _sdc.SubmitChanges();

                        _ok = true;
                    }
                    else
                    {
                        throw new Exception("不能重复添加对象");
                    }
                }
            }
            catch (Exception _e)
            {
                throw new Exception(_errorHead + _e.Message);
            }
            return _ok;
        }
        
        /// <summary>
        /// 保存对象
        /// </summary>
        /// <typeparam name="T">要保存的对象类型</typeparam>
        /// <param name="_o">插入时用到的空对象</param>
        /// <param name="_getObject">检验对象是否已存在的条件</param>
        /// <param name="_insertDuplication">插入对象时的重复检测条件</param>
        /// <param name="_insertImplement">插入对象时的委托实现</param>
        /// <param name="_updateDuplication">编辑对象时的重复检测条件</param>
        /// <param name="_updateImplement">编辑对象时的委托实现</param>
        /// <param name="_errorHead">错误信息标头</param>
        public static bool Save<T>(T _o, Func<T, bool> _getObject,
            Func<T, bool> _insertDuplication,
            Action<T> _insertImplement,
            Func<T, bool> _updateDuplication,
            Action<T> _updateImplement,
            string _errorHead) where T : class
        {
            bool _ok = false;
            try
            {
                using (var _sdc = DBHelper.GetDataContext())
                {
                    T _object = _sdc.GetTable<T>().Where(_getObject).FirstOrDefault();
                    if (_object == null)
                    {
                        //Insert
                        var _insert = _sdc.GetTable<T>().FirstOrDefault(_insertDuplication);
                        if (_insert == null)
                        {
                            _insertImplement(_o);
                            _sdc.GetTable<T>().InsertOnSubmit(_o);

                            _sdc.SubmitChanges();

                            _ok = true;
                        }
                        else
                        {
                            throw new Exception("不能重复添加对象");
                        }
                    }
                    else
                    {
                        //Update
                        var _update = _sdc.GetTable<T>().FirstOrDefault(_updateDuplication);
                        if (_update == null)
                        {
                            _updateImplement(_object);

                            _sdc.SubmitChanges();

                            _ok = true;
                        }
                        else
                        {
                            throw new Exception("已存在相同内容对象");
                        }
                    }
                }
            }
            catch (Exception _e)
            {
                throw new Exception(_errorHead + _e.Message);
            }

            return _ok;
        }
        
        /// <summary>
        /// 保存对象
        /// </summary>
        /// <typeparam name="T">要保存的对象类型</typeparam>
        /// <param name="_o">插入时用到的空对象</param>
        /// <param name="_getObject">检验对象是否已存在的条件</param>
        /// <param name="_insertDuplication">插入对象时的重复检测条件</param>
        /// <param name="_insertImplement">插入对象时的委托实现</param>
        /// <param name="_updateImplement">编辑对象时的委托实现</param>
        /// <param name="_errorHead">错误信息标头</param>
        public static bool Save<T>(T _o, Func<T, bool> _getObject,
            Func<T, bool> _insertDuplication,
            Action<T> _insertImplement,
            Action<T> _updateImplement,
            string _errorHead) where T : class
        {
            bool _ok = false;
            try
            {
                using (var _sdc = DBHelper.GetDataContext())
                {
                    T _object = _sdc.GetTable<T>().Where(_getObject).FirstOrDefault();
                    if (_object == null)
                    {
                        //Insert
                        var _insert = _sdc.GetTable<T>().FirstOrDefault(_insertDuplication);
                        if (_insert == null)
                        {
                            _insertImplement(_o);
                            _sdc.GetTable<T>().InsertOnSubmit(_o);

                            _sdc.SubmitChanges();

                            _ok = true;
                        }
                        else
                        {
                            throw new Exception("不能重复添加对象");
                        }
                    }
                    else
                    {
                        //Update
                            _updateImplement(_object);

                            _sdc.SubmitChanges();

                            _ok = true;
                    }
                }
            }
            catch (Exception _e)
            {
                throw new Exception(_errorHead + _e.Message);
            }
            return _ok;
        }
        
    }
}
